package net.xiaoboli.mgp;

import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.logging.Log;
import org.mybatis.generator.logging.LogFactory;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class LombokPlugin extends PluginAdapter {

    private boolean addApiModelProperty = false;
    private Set<String> apiModelPropertyHiddenSet = new HashSet<>();
    private Set<String> ignoresSet = new HashSet<>();
    private String dateFormat = "";
    private Log log;

    @Override
    public void initialized(IntrospectedTable introspectedTable) {
        this.log = LogFactory.getLog(this.getClass());
        this.dateFormat = properties.getProperty("dateFormat", "yyyy-MM-dd'T'HH:mm:ssZ");
        //
        String df1 = introspectedTable.getTableConfiguration().getProperty("dateFormat");
        if (StringUtils.isNotBlank(df1)) {
            this.dateFormat = df1;
        }
        //
        String ignores = introspectedTable.getTableConfiguration().getProperty("ignores");
        if (!StringUtils.isBlank(ignores)) {
            String[] items = ignores.split(",");
            for (String item : items) {
                this.ignoresSet.add(item);
            }
        }
    }

    @Override
    public boolean validate(List<String> list) {
        this.addApiModelProperty = "true".equals(properties.getProperty("addApiModelProperty"));
        String apiModelPropertyHidden = properties.getProperty("apiModelPropertyHidden");
        if (!StringUtils.isEmpty(apiModelPropertyHidden)) {
            String[] items = apiModelPropertyHidden.split(",");
            for (String item : items) {
                this.apiModelPropertyHiddenSet.add(item);
            }
        }
        return true;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

        //添加domain的import
        topLevelClass.addImportedType("lombok.Data");
//        topLevelClass.addImportedType("lombok.Builder");
//        topLevelClass.addImportedType("lombok.NoArgsConstructor");
//        topLevelClass.addImportedType("lombok.AllArgsConstructor");

        //添加domain的注解
        topLevelClass.addAnnotation("@Data");
//        topLevelClass.addAnnotation("@Builder");
//        topLevelClass.addAnnotation("@NoArgsConstructor");
//        topLevelClass.addAnnotation("@AllArgsConstructor");

        //添加domain的注释
//        topLevelClass.addJavaDocLine("/**");
        //topLevelClass.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
//        topLevelClass.addJavaDocLine("* Created by mgp-generator on " + date2Str(new Date()));
//        topLevelClass.addJavaDocLine("*/");

        return true;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        //Mapper文件的注释
//        interfaze.addJavaDocLine("/**");
        //interfaze.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
//        interfaze.addJavaDocLine("* Created by mgp-generator on " + date2Str(new Date()));
//        interfaze.addJavaDocLine("*/");
        return true;
    }

    @Override
    public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        //force @column to updateByPrimaryKeySelective and insert
        List<String> annotations = field.getAnnotations();
        for (int i = annotations.size() - 1; i > -1; i--) {
            String s = annotations.get(i);
            if (s.startsWith("@Column(name")) {
                annotations.remove(i);
            }
        }

        //禁止输出字段
        if (this.ignoresSet.contains(introspectedColumn.getActualColumnName())) {
            topLevelClass.addImportedType(new FullyQualifiedJavaType("com.fasterxml.jackson.annotation.JsonIgnore"));
            field.addAnnotation("@JsonIgnore");
        }

        //topLevelClass.addImportedType(new FullyQualifiedJavaType("javax.persistence.Column"));
        annotations.add("@Column(name = \"" + introspectedColumn.getActualColumnName() + "\")");

        //
        if (this.addApiModelProperty) {
            String remarks = introspectedColumn.getRemarks();
            if (!StringUtils.isEmpty(remarks)) {
                topLevelClass.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModelProperty"));
                remarks = remarks.replace("\"", "");

                // introspectedColumn.isNullable()
                StringBuffer buffer = new StringBuffer();
                buffer.append("@ApiModelProperty(");
                buffer.append("value = \"" + remarks + "\"");

                if (this.apiModelPropertyHiddenSet.contains(introspectedColumn.getActualColumnName())) {
                    buffer.append(", hidden = true");
                }

                buffer.append(")");
                field.addAnnotation(buffer.toString());
            }
        }


        String df = this.dateFormat;
        //
        String df1 = introspectedTable.getTableConfiguration().getProperty("dateFormat:" + introspectedColumn.getActualColumnName());
        if (StringUtils.isNotBlank(df1)) {
            df = df1;
        }
        //
        if (StringUtils.isNotBlank(df) && field.getType().getFullyQualifiedName().equals("java.util.Date")) {
            topLevelClass.addImportedType(new FullyQualifiedJavaType("org.springframework.format.annotation.DateTimeFormat"));
            topLevelClass.addImportedType(new FullyQualifiedJavaType("com.fasterxml.jackson.annotation.JsonFormat"));
            field.addAnnotation("@JsonFormat(pattern = \"" + df + "\")");
            field.addAnnotation("@DateTimeFormat(pattern = \"" + df + "\")");
        }

        return super.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
    }

    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        //不生成getter
        return false;
    }

    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        //不生成setter
        return false;
    }

    private String date2Str(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        return sdf.format(date);
    }


}
